/*
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 3 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <stdexcept>
#include <QtUiTools>
#include <QtGui>
#include <QMessageBox>
#include <QSettings>
#include <QFileDialog>

#include "mainwindow.h"
#include "chanmanager.h"
#include "standardchanmanager.h"
#include "components/chan.h"
#include "chanlisteditor.h"
#include "components/board.h"
#include "components/post.h"
#include "components/thread.h"
#include "log.h"
#include "postitemmodel.h"
#include "imageview.h"
#include "boardsettingsdialog.h"
#include "imagestorage.h"
#include "imagelist.h"
#include "threaditemmodel.h"
#include "threaditemdelegate.h"
#include "paths.h"
#include "tasklist.h"
#include "threadsaver.h"
#include "threadbuilder.h"
#include "exportthreaddialog.h"
#include "tasks/tasksavethread.h"
#include "settingsframe.h"
#include "ui_imageview.h"
#include "ui_mainwindow.h"
#include "threadlistmodel.h"
#include "filtertext.h"
#include "ui/mainwindowcontroller.h"
#include "sqlitethreadstorage.h"
#include "chanwatcher.h"

Wishmaster::ImageStorage* g_imagestorage;
using namespace Wishmaster;

MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent),
	m_ui(new Ui::MainWindow())
{
	m_ui->setupUi(this);

	m_progressBar = new QProgressBar(statusBar());
	statusBar()->addPermanentWidget(m_progressBar);
	m_progressBar->hide();

	m_ui->list_threads->setModel(new ThreadItemModel(ThreadItemModel::mVisible, NULL));
	m_ui->list_threads->setItemDelegate(new ThreadItemDelegate(m_ui->list_threads));
	m_ui->list_hidden->setModel(new ThreadItemModel(ThreadItemModel::mHidden, NULL));
	m_ui->list_hidden->setItemDelegate(new ThreadItemDelegate(m_ui->list_hidden));
	m_ui->list_archive->setModel(new ThreadItemModel(ThreadItemModel::mArchive, NULL));
	m_ui->list_archive->setItemDelegate(new ThreadItemDelegate(m_ui->list_archive));
	m_ui->tw_content->clear();

	g_imagestorage = new Wishmaster::ImageStorage();
	m_imageView = new ImageViewForm(this);
	m_imageManager = new ImageManager(this);
	m_settingsFrame = new SettingsFrame(this, m_chanmanager, this);
	m_postedit = NULL;

	restoreWindowAndSplitterStates();

	enableThreadButtons(false);
}

void MainWindow::restoreWindowAndSplitterStates()
{
	QSettings settings;
	restoreGeometry(settings.value("geometry/mainwindow").toByteArray());

	QList<int> sizes;
	if(!m_ui->splitter->restoreState(settings.value("geometry/splitter").toByteArray()))
	{
		sizes.clear();
		sizes.append(200);
		sizes.append(600);
		m_ui->splitter->setSizes(sizes);
	}
	sizes = m_ui->splitter->sizes();
	if(m_ui->splitter->orientation() == Qt::Vertical)
		m_ui->splitter->setOrientation(Qt::Horizontal);
}

bool MainWindow::initialize()
{
	QSettings settings;

	m_currentStyle = PostStylePtr(new PostStyle());
	QString style = loadPostStyle();
	if(!style.isEmpty())
		m_currentStyle->loadStyle(style);

	if(!settings.value("first_run6_1").toBool())
	{
		settings.setValue("rirst_run6_1", true);
		settings.setValue("autorefresh/lazy", true);
	}

	return true;
}

MainWindow::~MainWindow()
{
	if(m_postedit)
		delete m_postedit;
	m_chanmanager->shutdown();
	delete m_chanmanager;
	m_chanmanager = NULL;
	if(m_settingsFrame)
	{
		delete m_settingsFrame;
		m_settingsFrame = NULL;
	}
}

void MainWindow::setChanManager(Wishmaster::ChanManager* manager)
{
	m_chanmanager = manager;
	m_chanmanager->setImageView(m_imageView);
	createController();
}

void MainWindow::createController()
{
	m_controller = new Wishmaster::MainWindowController(m_chanmanager, this);
	connect(m_controller, SIGNAL(boardListChanged(QStringList)), this, SLOT(boardListChanged(QStringList)));
	connect(m_controller, SIGNAL(threadListChanged()), this, SLOT(refreshThreadList()));
	connect(m_controller, SIGNAL(threadActivated(ThreadId)), this, SLOT(threadActivated(ThreadId)));
}

MainWindowController* MainWindow::controller() const
{
	return m_controller;
}

void MainWindow::cb_board_index_changed(int index)
{
	m_controller->setActiveBoardIndex(index);
}

void MainWindow::thread_activate(QModelIndex const& index)
{
	if(!(qApp->mouseButtons() & Qt::LeftButton))
		return;
	ThreadId threadId = index.data(ThreadItemModel::FullThreadIdRole).value<ThreadId>();
	m_controller->setActiveThreadId(threadId);
}

void MainWindow::archiveThreadActivate(const QModelIndex& index)
{
	if(!(qApp->mouseButtons() & Qt::LeftButton))
		return;
	ThreadId threadId = index.data(ThreadItemModel::FullThreadIdRole).value<ThreadId>();
	m_controller->setActiveThreadId(threadId);
}

void MainWindow::threadActivated(const ThreadId& threadId)
{
	showThread(threadId);
	//updateAddressBar();
}

void MainWindow::linkClicked(const QString& link)
{
	log(llDebug, "MainWindow::linkClicked(%s)", qPrintable(link));
	ChanList* list = m_chanmanager->chanlist();
	QUrl url(link);
	QString host = url.host();

	Chan* chan = list->getChan(host);
	if(!chan)
	{
		host = host.section('.', 1);
		chan = list->getChan(host);
		if(!chan)
			return;
	}

	Board* b = chan->board(0);
	if((!b) || (!b->parser()))
		return;

	PostId postId = b->parser()->parseLink(link);
	if(!postId.isValid())
		return;

	log(llDebug, "postId: %s", qPrintable(postId.toString()));

	m_controller->setActiveThreadId(postId.getThreadId());
}

void MainWindow::showThread(const ThreadId& thread_id)
{
	ChanList* list = m_chanmanager->chanlist();
	Q_ASSERT(list);

	Wishmaster::ThreadPtr thread = list->getThread(thread_id);
	if(!thread)
	{
		Wishmaster::Board* b = list->getBoard(thread_id.chanName(), thread_id.boardId());
		if(!b)
			return;
		thread = Wishmaster::ThreadPtr(new Wishmaster::Thread(thread_id, b));
		b->visibleThreads()->push_back(thread);
	}
	PostItemView* piv = getTab(thread_id);
	if(!piv)
	{
		piv = newTab(thread_id);
		piv->setThread(thread);
	}
	m_ui->tw_content->setCurrentWidget(piv);

	enableThreadButtons(true);
}

void MainWindow::addPost()
{
	if(m_postedit)
		delete m_postedit;
	PostItemView* piv = currentTab();
	if(!piv)
		return;
	m_postedit = new PostEdit(m_chanmanager, piv->thread()->id(), this);
	m_postedit->setThreadOverviewVisible(true);
	m_postedit->updateThreadOverview();
	m_postedit->show();
}

void MainWindow::addPost(const QString& initial_text)
{
	if(m_postedit)
		delete m_postedit;
	PostItemView* piv = currentTab();
	if(!piv)
		return;
	m_postedit = new PostEdit(m_chanmanager, piv->thread()->id(), this);
	m_postedit->setText(initial_text);
	m_postedit->setThreadOverviewVisible(true);
	m_postedit->updateThreadOverview();
	m_postedit->show();
}

void MainWindow::createThread()
{
	if(m_postedit)
		delete m_postedit;
	m_postedit = new PostEdit(m_chanmanager, ThreadId(controller()->activeChan()->getHost(), controller()->activeBoard()->name(), 0), this);
	m_postedit->setThreadOverviewVisible(false);
	m_postedit->show();
}

void MainWindow::watchThread(bool t)
{
	ThreadId threadId = m_contextMenuThread;
	if(!threadId.isValid())
		return;
	Wishmaster::ThreadPtr thread = m_chanmanager->chanlist()->getThread(threadId);
	thread->setFlag(Thread::Watched, t);
	if(t)
		m_chanmanager->chanwatcher()->addToWatchList(threadId);
	else
		m_chanmanager->chanwatcher()->removeFromWatchList(threadId);
}

void MainWindow::hideThread()
{
	ThreadId threadId = m_contextMenuThread;
	if(!threadId.isValid())
		return;
	controller()->activeBoard()->hideThread(threadId);
	m_ui->list_threads->selectionModel()->clear();
	m_ui->list_threads->update();
	refreshThreadList();
}

void MainWindow::quit()
{
	close();
}

void MainWindow::show_content_context_menu(const QPoint& position)
{
	PostItemView* piv = currentTab();
	if(!piv)
		return;
	QList<QAction*> actions;
	if(piv->indexAt(position).isValid())
	{
		QString link = piv->linkAt(position);
		QString selection = piv->selectedText(position);
		actions.append(m_ui->actionShowPic);
		if(!link.isEmpty())
		{
			actions.append(m_ui->actionCopy_link);
			m_link = link;
		}
		if(!selection.isEmpty())
		{
			actions.append(m_ui->actionCopy);
			m_selection = selection;
		}
    }
	if(actions.count() > 0)
		QMenu::exec(actions, piv->mapToGlobal(position));
}

void MainWindow::show_threads_context_menu(const QPoint& position)
{
	QListView* list = qobject_cast<QListView*>(sender());
	if(!list)
	{
		log(llWarning, "Invalid signal sender");
		return;
	}
	QList<QAction*> actions;
	QModelIndex index = list->indexAt(position);
	if(index.isValid())
	{
		Wishmaster::Board* b = static_cast<Wishmaster::Board*>(index.data(ThreadItemModel::BoardRole).value<void*>());
		if(!b)
			return;

		m_contextMenuThread = index.data(ThreadItemModel::FullThreadIdRole).value<ThreadId>();
		QVariant threadid = index.data(ThreadItemModel::ThreadIdRole).toUInt();
		Wishmaster::ThreadPtr thread = b->getThread(ThreadId(b->getParent()->getHost(), b->name(), threadid.toUInt()));
		if(!thread)
			return;

		if(!thread->flag(Thread::Archived))
		{
			if(thread->flag(Thread::Alive))
			{
				m_ui->actionWatch_thread->setChecked(thread->flag(Thread::Watched));
				actions.append(m_ui->actionWatch_thread);
			}
			else
				actions.append(m_ui->actionSave_thread);

			if(thread->visibility() != Wishmaster::Hide &&
			   thread->visibility() != Wishmaster::HideForever)
				actions.append(m_ui->actionHide_thread);
		}
		else
			actions.append(m_ui->actionDelete_from_archive);
	}
	else
	{
		log(llWarning, "Invalid index");
		return;
	}
	if(actions.count() > 0)
		QMenu::exec(actions, list->mapToGlobal(position));
}

Ui::MainWindow* MainWindow::getUI()
{
	return m_ui;
}

ImageViewForm* MainWindow::getImageView()
{
	return m_imageView;
}

ImageManager* MainWindow::getImageManager()
{
	return m_imageManager;
}

void MainWindow::createDatabase()
{
	g_imagestorage->makeDB();
}

void MainWindow::imageManager()
{
	m_imageManager->setMode(false);
	m_imageManager->show();
}

void MainWindow::showSettings()
{
	SettingsFrame frame(this, m_chanmanager, this);
	frame.fillForm();
	frame.exec();
	QString style = loadPostStyle();
	if(!style.isEmpty())
	{
		m_currentStyle = PostStylePtr(new PostStyle());
		m_currentStyle->loadStyle(style);
	}
}

void MainWindow::closeEvent(QCloseEvent* event)
{
	QSettings settings;
	settings.setValue("geometry/mainwindow", saveGeometry());
	settings.setValue("geometry/splitter", m_ui->splitter->saveState());
	QMainWindow::closeEvent(event);

}

void MainWindow::chanChanged(int i)
{
	m_controller->setActiveChanIndex(i);
}

void MainWindow::copy()
{
	QApplication::clipboard()->setText(m_selection);
}

void MainWindow::copyLink()
{
	QApplication::clipboard()->setText(m_link);
}

void MainWindow::boardSettings()
{
	Wishmaster::Board* b = controller()->activeBoard();
	if(!b)
	{
		log(llError, "Invalid board");
		return;
	}
	BoardSettingsDialog settingsdlg(m_chanmanager->chanwatcher(), b, this);
	connect(&settingsdlg, SIGNAL(accepted()), b, SLOT(settingsChanged()));
	settingsdlg.exec();
}

QProgressBar* MainWindow::progressBar()
{
	return m_progressBar;
}

void MainWindow::downloadAttachment(const PostId& postId, int index)
{
	m_chanmanager->showPicture(postId, index);
}

void MainWindow::expandThread()
{
}

bool MainWindow::event(QEvent* event)
{
	if(event->type() == QEvent::LanguageChange)
	{
		m_ui->retranslateUi(this);
		return true;
	}
	return QMainWindow::event(event);
}

void MainWindow::enableThreadButtons(bool e)
{
	m_ui->actionReply_to_the_thread->setEnabled(e);
	m_ui->actionExpand_thread->setEnabled(e);
	m_ui->actionImageList->setEnabled(e);
	m_ui->actionZoom_Text->setEnabled(e);
	m_ui->actionUnzoom_Text->setEnabled(e);
	m_ui->actionSave_thread_on_disk->setEnabled(e);
}

QString MainWindow::loadPostStyle()
{
	QSettings settings;
	QString fname = settings.value("interface/stylefile").toString();
	if(fname.isEmpty())
		return QString::null;
	QFile f(fname);
	if(!f.open(QIODevice::ReadOnly))
		return QString::null;
	return QString::fromUtf8(f.readAll());
}

PostItemView* MainWindow::newTab(const ThreadId& threadId)
{
	QSettings settings;

	PostItemView* piv = new PostItemView(this);
	piv->setPostStyle(m_currentStyle);


	QVariant postfont = settings.value("interface/defaultPostFont");
	if(postfont.isValid())
		piv->setDefaultPostFont(postfont.value<QFont>());

	QVariant headerfont = settings.value("interface/defaultHeaderFont");
	if(headerfont.isValid())
		piv->setDefaultHeaderFont(headerfont.value<QFont>());

	QVariant notefont = settings.value("interface/defaultNoteFont");
	if(notefont.isValid())
		piv->setDefaultNoteFont(notefont.value<QFont>());

	piv->setSpacing(4);
	QString tabname = threadId.chanName() + threadId.boardId() + threadId.threadStringId();
	m_ui->tw_content->addTab(piv, QPixmap::fromImage(m_chanmanager->chanlist()->getChan(threadId.chanName())->icon()), tabname);
	piv->setModel(new ThreadListModel(NULL));
	piv->setContextMenuPolicy(Qt::CustomContextMenu);
	piv->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
	piv->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
	connect(piv, SIGNAL(reply(QString)), this, SLOT(addPost(QString)));
	connect(piv, SIGNAL(downloadAttachment(PostId, int)), this, SLOT(downloadAttachment(PostId, int)));
	connect(piv, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(show_content_context_menu(QPoint)));
	connect(piv, SIGNAL(linkClicked(QString)), this, SLOT(linkClicked(QString)));
	enableThreadButtons(true);
	piv->setImageHideMode(m_ui->actionHide_images->isChecked());
	return piv;
}

PostItemView* MainWindow::getTab(const ThreadId& threadId)
{
	for(int i = 0; i < m_ui->tw_content->count(); i++)
	{
		PostItemView* piv = qobject_cast<PostItemView*>(m_ui->tw_content->widget(i));
		if(!piv)
			continue;
		if(piv->thread()->id() == threadId)
		{
			return piv;
		}
	}
	return 0;
}

PostItemView* MainWindow::currentTab() const
{
	return qobject_cast<PostItemView*>(m_ui->tw_content->currentWidget());
}

void MainWindow::closeTab(int index)
{
	QWidget* w = m_ui->tw_content->widget(index);
	PostItemView* piv = qobject_cast<PostItemView*>(w);
	m_ui->tw_content->removeTab(index);
	if(piv)
	{
		delete piv->model();
		if(m_ui->tw_content->count() == 0)
			enableThreadButtons(false);
	}
	delete w;
}

void MainWindow::tabChanged(int index)
{
	PostItemView* piv = qobject_cast<PostItemView*>(m_ui->tw_content->widget(index));
	if(!piv)
		return;
	piv->viewport()->update();
	Wishmaster::Board* board = piv->board();
	if(!board)
		return;
	Wishmaster::Chan* chan = board->getParent();
	if(!chan)
		return;
	Wishmaster::ThreadPtr thread = piv->thread();
	if(thread.isNull())
		return;
	updateContent(PostId(thread->id(), 0), 0);
	m_ui->actionHide_images->setChecked(piv->isImageHideMode());

	//updateAddressBar();
}

void MainWindow::refreshTabs()
{
	for(int i = 0; i < m_ui->tw_content->count(); i++)
	{
		PostItemView* piv = qobject_cast<PostItemView*>(m_ui->tw_content->widget(i));
		if(!piv)
			continue;
		Wishmaster::Board* board = piv->board();
		if(!board)
			continue;
		Wishmaster::Chan* chan = board->getParent();
		if(!chan)
			continue;
		Wishmaster::ThreadPtr thread = piv->thread();
		if(thread.isNull())
			continue;
		m_chanmanager->requestThread(thread->id());
	}
}

void MainWindow::imageList()
{
	PostItemView* piv = currentTab();
	if(!piv)
		return;
	Wishmaster::ThreadPtr thread = piv->thread();
	if(thread.isNull())
		return;
	ImageList imagelist(m_chanmanager->requestManager(), this);
	imagelist.setThread(thread);
	imagelist.exec();
}

bool MainWindow::editChanlist()
{
	QString chans = Wishmaster::DefaultPath::storageRoot() + QDir::separator() + "chans.xml";
	ChanListEditor dlg(this);
	dlg.loadChanlist(chans);
	if(dlg.exec() == QDialog::Accepted)
	{
		while(m_ui->tw_content->count())
		{
			QWidget* w = m_ui->tw_content->widget(0);
			m_ui->tw_content->removeTab(0);
			delete w;
		}
		//m_chanmanager->rereadChanlist();
		QSettings settings;
		if(!settings.value("autorefresh/lazy").toBool())
			m_chanmanager->refresh(true, true);
		return true;
	}
	return false;
}

void MainWindow::boardListChanged(const QStringList& boardlist)
{
	m_ui->cb_board->clear();
	m_ui->cb_board->addItems(boardlist);
	m_controller->setActiveBoardIndex(0);
}

void MainWindow::chanListChanged(const QStringList& chanlist)
{
	m_ui->cb_chan->clear();
	m_ui->cb_chan->addItems(chanlist);
}

void MainWindow::updateContent(const PostId& postId, int attachmentIndex)
{
	Wishmaster::Chan* ch = m_chanmanager->chanlist()->getChan(postId.chan());
	if(!ch)
		return;
	Wishmaster::Board* b = ch->board(postId.board());
	if(!b)
		return;
	Wishmaster::ThreadPtr thread = b->getThread(postId.getThreadId());
	if(!thread)
		return;

	if(postId.postId() == 0)
	{
		updateLeaderPic(postId.getThreadId());
	}

	PostItemView* pv = getTab(thread->id());
	if(pv)
	{
		bool current = (pv == currentTab());
		if(current)
		{
			m_ui->tw_content->setUpdatesEnabled(false);
			pv->setUpdatesEnabled(false);
		}

		QModelIndexList l = pv->selectionModel()->selectedRows();
		QModelIndex sel;
		if(!l.isEmpty())
			sel = l.at(0);

		pv->updateContent();

		if(postId.postId())
		{
			pv->changed(thread->getPostPosition(postId));
		}
		else if(current)
		{
			pv->changed(-1);
		}
		if(current)
		{
			pv->update();
			pv->viewport()->update();
			pv->selectionModel()->select(sel, QItemSelectionModel::ClearAndSelect);
			pv->setUpdatesEnabled(true);
			m_ui->tw_content->setUpdatesEnabled(true);
		}
	}
	m_ui->list_threads->viewport()->update();
}

void MainWindow::updateLeaderPic(const ThreadId& threadId)
{
	ThreadItemModel* model = qobject_cast<ThreadItemModel*>(m_ui->list_threads->model());
	if(!model)
		return;

	int row = model->getThreadRow(threadId);
	if(row < 0)
		return;

	model->update(row);
}

void MainWindow::updateAddressBar()
{
	ThreadId threadId = getCurrentThreadId();
	m_ui->addressBar->clear();

	Wishmaster::ChanList* chanlist = m_chanmanager->chanlist();

	AddressBarElementPtr chanElement = AddressBarElement::create();
	chanElement->setText(threadId.chanName());
	m_ui->addressBar->addElement(chanElement);

	AddressBarElementPtr boardElement = AddressBarElement::create();
	boardElement->setText(chanlist->getBoard(threadId.chanName(), threadId.boardId())->alias());
	m_ui->addressBar->addElement(boardElement);

	AddressBarElementPtr threadElement = AddressBarElement::create();
	threadElement->setText(chanlist->getThread(threadId)->getShortName());
	m_ui->addressBar->addElement(threadElement);
}

void MainWindow::updateBoardIndex(const QString& chanName, const QString& boardName)
{
	log(llDebug, "MainWindow::updateBoardIndex");
	ChanList* list = m_chanmanager->chanlist();
	Q_ASSERT(list);

	Chan* chan = list->getChan(m_controller->activeChanIndex());
	if(!chan)
		return;

	Board* board = chan->board(m_controller->activeBoardIndex());
	if(!board)
		return;

	if((chan->name() != chanName) || (board->name() != boardName))
		return;

	refreshThreadList();
}

unsigned long MainWindow::getSelectedThread()
{
	// TODO: other lists
	return m_ui->list_threads->model()->data(m_ui->list_threads->currentIndex(), Wishmaster::ChanManager::ThreadIdRole).toUInt();
}

void MainWindow::zoomPostFont()
{
	currentTab()->zoom();
}

void MainWindow::unzoomPostFont()
{
	currentTab()->unzoom();
}

void MainWindow::showTasklist()
{
	TaskList* tasklist = new TaskList(m_chanmanager->taskhub());
	m_ui->tw_content->addTab(tasklist, tr("Tasks"));
} 

QListView* MainWindow::threadsListView()
{
	return m_ui->list_threads;
}

QListView* MainWindow::hiddenListView()
{
	return m_ui->list_hidden;
}

QListView* MainWindow::archiveListView()
{
	return m_ui->list_archive;
}

void MainWindow::exportThread()
{
	PostItemView* piv = currentTab();
	if(piv)
	{
		ExportThreadDialog dlg(this);
		if(dlg.exec() == QDialog::Accepted)
		{
			Wishmaster::ThreadBuilderPtr builder = dlg.builder();
			ThreadPtr thread = piv->thread();
			QString path = QFileDialog::getSaveFileName(this, tr("Save thread"), QString(), builder->filter());

			TaskSaveThread* task = new TaskSaveThread(thread, m_chanmanager->connector(),m_chanmanager->taskhub(),
					builder, path, tr("Saving thread: ") + thread->id().threadStringId());
			TaskPtr t(task);
			m_chanmanager->taskhub()->queueTask(t);
		}
	}
}

void MainWindow::hideImages(bool b)
{
	for(int i = 0; i < m_ui->tw_content->count(); i++)
	{
		PostItemView* piv = qobject_cast<PostItemView*>(m_ui->tw_content->widget(i));
		if(!piv)
			continue;
		piv->setImageHideMode(b);
	}
}

void MainWindow::deleteFromArchive()
{
	QModelIndex selected = m_ui->list_archive->selectionModel()->currentIndex();
	unsigned long thread_id = selected.data(ThreadItemModel::ThreadIdRole).toUInt();
	Wishmaster::Board* board = static_cast<Wishmaster::Board*>(selected.data(ThreadItemModel::BoardRole).value<void*>());
	Wishmaster::Chan* chan = board->getParent();
	board->archivedThreads()->pick(ThreadId(chan->getHost(), board->name(), thread_id));
	unsigned long id_in_storage = chan->threadStorage()->thread(chan->getHost(), board->name(), thread_id);
	chan->threadStorage()->deleteThread(id_in_storage);
}

void MainWindow::chanIconChanged(int index)
{
	m_ui->cb_chan->setItemIcon(index, QPixmap::fromImage(m_chanmanager->chanlist()->getChan(index)->icon()));
	m_ui->cb_chan->updateGeometry();
}

void MainWindow::refreshThreadList()
{
	refreshThreadListView(threadsListView());
	refreshThreadListView(hiddenListView());
	refreshThreadListView(archiveListView());
}

void MainWindow::refreshThreadListView(QListView* listview)
{
	Board* b = m_controller->activeBoard();
	QAbstractItemModel* abstract_model = listview->model();
	ThreadItemModel* model = qobject_cast<ThreadItemModel*>(abstract_model);
	Q_ASSERT(model);
	model->setBoard(b);
}


ThreadId MainWindow::getCurrentThreadId() const
{
	if(!currentTab())
		return ThreadId();
	return currentTab()->thread()->id();
}
